package de.playmee;

import java.util.ArrayList;
import java.util.List;

import de.playmee.dialogs.CustomDialog;
import de.playmee.dialogs.EditMusicDialog;
import de.playmee.dialogs.ProgressWheelDialog;
import de.playmee.handler.MusicHandler;
import de.playmee.services.LoadingService;
import de.playmee.services.LoadingService.DownloadTrackDataListener;
import de.playmee.services.LoadingService.UploadTrackDataListener;
import de.playmee.views.ProgressBarHorizontalView;
import de.playmee.views.SimpleLibraryViewAdapter;
import de.playmee.views.ViewPagerAdapter;
import de.playmee.views.ViewPagerIndicator;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class RatingActivity extends MainMenuActivity {

	private final String TAG = "RatingActivity";
	
	private Playmee application;
	private MusicHandler mHandler;
	
	private ProgressWheelDialog progressWheelDialog;
	
	private List<Track> allTracks;
	private List<Track> unratedTracks;
	private List<Track> ratedTracks;
	private final String SORT_ORDER = MusicHandler.ORDER_BY_ARTIST_TITLE_ABC;
	
	private LinearLayout layoutView;
	private ProgressBarHorizontalView progressBarView;
	private int totalCount;
	
	private Handler downloadTrackDataHandler;
	private Handler initHandler;
	
	private ViewPager viewPager;
	private ViewPagerIndicator indicator;
	private final int DEFAULT_PAGE = 0; // unrated tracks
	
	/**
	 * called when the activity is first created
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		application = (Playmee) getApplication();
		mHandler = application.getMusicHandler();
		totalCount = mHandler.getMusicInDbCount();
		
		progressWheelDialog = new ProgressWheelDialog(this);
		
		downloadTrackDataHandler = new Handler() {
			public void  handleMessage(Message msg) {
				if (msg.what == -1) {
					// data of all tracks downloaded: show list
					refreshView(DEFAULT_PAGE);
				} else {
					// data of a single track downloaded: update the progress bar
					progressBarView.setProgress(msg.what);
				}
			}
		};
		
		// download track data listener
		application.addDownloadTrackDataListener(new DownloadTrackDataListener() {
			@Override
			public void onSingleTrackDataDownloaded(Track track) {
				downloadTrackDataHandler.sendEmptyMessage(totalCount - mHandler.getCheckCount());
			}

			@Override
			public void onAllTracksDataDownloaded() {
				downloadTrackDataHandler.sendEmptyMessage(-1);
			}
		});
		
		// get layout view
		setContentView(R.layout.rating);
		layoutView = (LinearLayout) findViewById(R.id.rating_layout);
		
		// create new progress bar and add it to the layout
		progressBarView = new ProgressBarHorizontalView(this, totalCount);
		progressBarView.setPadding(10, 10, 10, 10);
		layoutView.addView(progressBarView);
		
		// handler to handle refreshing the views (maybe with some extra work to do)
		initHandler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				// no context factors
				if (msg.what == -1) {
					Toast.makeText(RatingActivity.this, "No contextual factors defined. Old factors were recovered.", Toast.LENGTH_LONG).show();
				}
				// track attributes were updated
				else if (msg.what == 0) {
					// refresh view and start uploading tracks
					// TODO check internet connection
					progressWheelDialog.show();
					refreshView(DEFAULT_PAGE);
					startService(new Intent(LoadingService.ACTION_UPLOAD_TRACK));
				}
				// all track uploaded
				else if (msg.what == 1) {
					refreshView(DEFAULT_PAGE);
					progressWheelDialog.dismiss();
				}
			}
		};
		
		// upload track data listener
		application.addUploadTrackDataListener(new UploadTrackDataListener() {
			@Override
			public void onSingleTrackDataUploaded(Track track) {
				// nothing to do
			}

			@Override
			public void onAllTracksDataUploaded() {
				initHandler.sendEmptyMessage(1);
			}
		});
		
		// initialize ViewPager and its indicator
		// and refresh the view
		init();
	}
	
	/**
	 * creates the ViewPager and its indicator
	 */
	private void init() {
		Log.i(TAG, "Initialyzing ViewPager...");
		
		// get viewPager and indicator
		viewPager = (ViewPager) findViewById(R.id.rating_viewPager);
		indicator = (ViewPagerIndicator) findViewById(R.id.rating_indicator);
		viewPager.setOnPageChangeListener(indicator);
				
		refreshView(DEFAULT_PAGE);
		
		// set arrows of the indicator
		Resources res = getResources();
		Drawable prev = res.getDrawable(R.drawable.arrow_left_float);
		Drawable next = res.getDrawable(R.drawable.arrow_right_float);
		indicator.setArrows(prev, next);
		
		Log.i(TAG, "Done initialyzing ViewPager.");
	}
	
	/**
	 * refreshes the view
	 * 
	 * @param page
	 */
	private void refreshView(int page) {
		if (mHandler.getCheckCount() == 0) {
			// hide progress bar
			progressBarView.setVisibility(ProgressBarHorizontalView.GONE);
			
			// show ViewPager and its indicator
			viewPager.setVisibility(ViewPager.VISIBLE);
			indicator.setVisibility(ViewPagerIndicator.VISIBLE);
			
			// load tracks and classify them
			allTracks = mHandler.loadTracks(null, SORT_ORDER, true);
			ratedTracks = new ArrayList<Track>();
			unratedTracks = new ArrayList<Track>();
			for (Track track : allTracks) {
				if (track.isRated()) {
					ratedTracks.add(track);
				} else {
					unratedTracks.add(track);
				}
			}
			
			// create new adapter and initialize indicator
			ViewPagerAdapter adapter = new ViewPagerAdapter(this);
			addPages(adapter);
			viewPager.setAdapter(adapter);
			viewPager.setCurrentItem(page);
			indicator.init(
					page /* page to start on */,
					adapter.getCount() /* pages in total */,
					adapter /* callback to get page titles */);
		} else {
			// hide ViewPager and its indicator
			viewPager.setVisibility(ViewPager.GONE);
			indicator.setVisibility(ViewPagerIndicator.GONE);
						
			// show progress bar
			progressBarView.setVisibility(ProgressBarHorizontalView.VISIBLE);
			progressBarView.setTitle("Downloading music data...");
			progressBarView.setProgress(totalCount - mHandler.getCheckCount());
		}
	}
	
	/**
	 * adds views of the rating tab to the ViewPager adapter
	 * 		- all
	 * 		- rated
	 * 		- unrated
	 * 
	 * @param adapter
	 */
	private void addPages(ViewPagerAdapter adapter) {
		// adapter.addView(createView(allTracks), "All");
		adapter.addView(createView(unratedTracks), "Unrated");
		adapter.addView(createView(ratedTracks), "Rated");
	}
	
	/**
	 * creates a view to display the given tracks
	 * 
	 * @param tracks
	 */
	private View createView(List<Track> tracks) {		
		LinearLayout layout = new LinearLayout(this);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setPadding(10, 10, 10, 10);
		
		// create header
		TextView headerView = new TextView(this);
		headerView.setTextAppearance(this, android.R.attr.textAppearanceSmall);
		headerView.setText(tracks.isEmpty() ? "No music available." : tracks.size() + " music track(s):");
		headerView.setGravity(Gravity.CENTER);
		headerView.setPadding(0, 0, 0, 10);
		layout.addView(headerView);
		
		// create view to display tracks
		ListView tracksView = new ListView(this);
		tracksView.setCacheColorHint(Color.TRANSPARENT);
		SimpleLibraryViewAdapter tracksViewAdapter = new SimpleLibraryViewAdapter(this, mHandler, tracks);
		tracksView.setAdapter(tracksViewAdapter);
		tracksView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				showActionsDialog(mHandler.loadTrack(id, true));
			}});
		layout.addView(tracksView);
		
		return layout;
	}
	
	/**
	 * shows a dialog with all actions for a track
	 */
	private void showActionsDialog(final Track track) {
		if (track == null) return;
		
		final String DETAILS = "Show details";
		final String EDIT = "Edit Rating";
		final String CHECK = "Check again";
		// final String[] actionsEdit = { DETAILS, EDIT };
		// final String[] actionsNoEdit = { DETAILS, CHECK };
		final String[] actionsEdit = { EDIT };
		final String[] actionsNoEdit = { CHECK };
		
		final String[] actions;
		final String title;
		if (track.getIdDatabase() <= 0) { // 0 or -1
			actions = actionsNoEdit;
			title = "Unknown track";
		} else {
			actions = actionsEdit;
			title = track.getTitle();
		}

		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setIcon(android.R.drawable.ic_menu_manage);
		builder.setTitle(title);
		builder.setItems(actions, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int item) {
				CharSequence action = actions[item];
				
				// details
				if (action.equals(DETAILS)) {
					// launch dialog to show track details
					CustomDialog.showInfoDialog(RatingActivity.this, "Details", track.getInfo());
				}
				
				// edit
				else if (action.equals(EDIT)) {
					// launch dialog to edit track
					new EditMusicDialog(RatingActivity.this, mHandler, track, initHandler).show();
				}
				
				// check
				else if (action.equals(CHECK)) {
					// TODO check again if track could be found on last.fm
					Toast.makeText(RatingActivity.this, "TODO: check again on last.fm", Toast.LENGTH_LONG).show();
				}
			}
		});

		AlertDialog alert = builder.create();
		alert.show();
	}
}
